using namespace std;
#include<iostream>

#include<etcd/Client.hpp>
#include<etcd/Response.hpp>
#include<etcd/Value.hpp>
#include<etcd/Watcher.hpp>

#include"etcd.hpp"

//监测回调函数
void CallBack(const etcd::Response& resp)
{
    if (!resp.is_ok())
    {
        cout << "callback: " << resp.error_message() << endl;
        return;
    }

    // Returns the action type of the operation that this response belongs to.
    etcd::Events events = resp.events();
    // using Events = std::vector<Event>;
    for (auto& e : events)
    {
        if (e.event_type() == etcd::Event::EventType::PUT)
        {
            //添加 or 更新
            cout << "(Put) prev: " << e.prev_kv().key() << " - " << e.prev_kv().as_string() << endl;
            cout << "now: " << e.kv().key() << " - " << e.kv().as_string() << endl;
        }
        else if (e.event_type() == etcd::Event::EventType::DELETE_)
        {
            //服务下线
            cout << "服务下线：> " << e.prev_kv().key() << " - " << e.prev_kv().as_string() << endl;
        }
        else
        {
            //......
        }
    }
    
}

int main()
{/*
    //实例化etcd 客户端
    etcd::Client etcd_client("127.0.0.1:2379");

    //服务发现（获取键值）
    etcd::Response resp =  etcd_client.ls("/server").get();
    if (!resp.is_ok())
    {
        cout << "失败 'ls' > " << resp.error_message() << endl;
        return -1;
    }

    //typedef std::vector<std::string> Keys;
    size_t sz = resp.keys().size();//返回'ls'操作响应 的key值字典
    cout << "当前发现的服务：\n";
    for (int i = 0; i < sz; ++i)
    {
        etcd::Value kv = resp.value(i);
        cout << kv.key() << " " << kv.as_string() << endl;
    }
    cout << "------------------------------------" << endl;

    cout << "开始监测：\n";
    //动态检测
    // Watcher(Client const& client, std::string const& key,
        // std::function<void(Response)> callback, bool recursive = false);
    
    // callback这是一个回调函数，当被监听的键发生变化时，Watcher 会调用这个回调函数。
    // 回调函数接收一个 Response 对象作为参数，此对象包含了键变化的详细信息，比如变化的类型、新的值等。

    // bool recursive = false
    // 这是一个布尔类型的可选参数，默认值为 false。
    // 若将其设置为 true，Watcher 会递归地监听指定键及其所有子键的变化；若设置为 false，则仅监听指定键的变化。
    etcd::Watcher watcher(etcd_client, "/servers", CallBack, true);

    //阻塞等待，直到监控任务被终止
    watcher.Wait();
    watcher.Cancel();*/

    init_mylogger(false, "test", "", 0, false);
    std::unordered_map<std::string, std::string> servers_map;
    ns_etcd_client::Discovery("127.0.0.1:2379", "/servers", servers_map, 
                            [](const std::string k, const std::string v){cout << "PUT\n";},
                            [](const std::string k, const std::string v){cout << "DEL\n";},
                          true);

    return 0;
}